package com.qf.j2112.service;

import com.qf.j2112.po.SysMember;
import com.qf.j2112.po.SysOrder;
import com.qf.j2112.vo.Chargevo;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @ProjectName: YiZhanXiYi
 * @Package: com.qf.j2112.service
 * @ClassName: RabbitService
 * @Author: 宋晓博
 * @Description: description
 * @Date: 2022/4/22 16:24
 * @Version: 1.0
 */

@Component
@Slf4j
public class RabbitService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SysMemberService sysMemberService;

    @RabbitListener(queues = "reduceMoneyQueue")
    public void acceptMsg(SysOrder sysOrder, Channel channel, Message message) throws IOException {
        log.info("accept order :"+sysOrder);
//     如何确保此消息只被唯一签收（消息消费幂等性问题）
        //获取消息的协调id
        String correlationData =(String ) message.getMessageProperties().getHeaders().get("spring_returned_message_correlation");
//       以消息的id为key写入redis中
        if(redisTemplate.opsForValue().setIfAbsent(correlationData,"0",5, TimeUnit.SECONDS)){//key不存在，首次消费此消息
//        消费消息
            log.info(" 写订单成功 。msg："+new String (message.getBody()));
            SysMember sysMember = sysMemberService.selectSysMemberByUserId(sysOrder.getOrderUserId());
            sysMember.setMemberMoney(sysMember.getMemberMoney()-sysOrder.getOrderPaidmoney());
            int i = sysMemberService.updateSysMember(sysMember);
            if(i>-1){
                //修改此消息在redis中的状态码为以消费 例如 ：1
                redisTemplate.opsForValue().setIfAbsent(correlationData,"1",5, TimeUnit.SECONDS);
            }
        }else{//消息正在在消费，判断消息是否已成功消费，如果成功，则手动签收消息
            if("1".equals(redisTemplate.opsForValue().get(correlationData))){//正确消费消息
                //手动签收
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            }
        }
    }

    @RabbitListener(queues = "chargeQueue")
    public void acceptCharge(Chargevo chargevo, Channel channel, Message message) throws IOException {
        log.info("accept chargevo :"+chargevo);
//     如何确保此消息只被唯一签收（消息消费幂等性问题）
        //获取消息的协调id
        String correlationData =(String ) message.getMessageProperties().getHeaders().get("spring_returned_message_correlation");
//       以消息的id为key写入redis中
        if(redisTemplate.opsForValue().setIfAbsent(correlationData,"0",5, TimeUnit.SECONDS)){//key不存在，首次消费此消息
//        消费消息

            SysMember sysMember = sysMemberService.selectSysMemberByUserId(chargevo.getUserId());
            sysMember.setMemberMoney(sysMember.getMemberMoney()+chargevo.getMoney());
            int i = sysMemberService.updateSysMember(sysMember);
            if(i>-1){
                //修改此消息在redis中的状态码为以消费 例如 ：1
                redisTemplate.opsForValue().setIfAbsent(correlationData,"1",5, TimeUnit.SECONDS);
            }
            log.info(" 充值成功 。msg："+new String (message.getBody()));
        }else{//消息正在在消费，判断消息是否已成功消费，如果成功，则手动签收消息
            if("1".equals(redisTemplate.opsForValue().get(correlationData))){//正确消费消息
                //手动签收
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            }
        }
    }
}
